package com.talkyun.ocean;

import com.talkyun.ocean.impl.LocalRegistryManager;
import com.talkyun.ocean.model.Endpoint;
import com.talkyun.ocean.model.Provider;
import com.talkyun.ocean.model.Service;
import com.talkyun.ocean.service.RegistryManager;
import com.talkyun.ocean.utils.StreamReader;
//import com.talkyun.openx.RestfulServiceFactory;
import com.talkyun.utils.ObjectId;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RegistryClient {
    private final Map<String, Service> cache = new ConcurrentHashMap<String, Service>();
    private RegistryManager rm;
    private String registryUrl;

    public RegistryClient() {
        rm = new LocalRegistryManager();
    }

    public RegistryClient(String url) {
        if (url.startsWith("http://") || url.startsWith("https://")) {
            // registry center
            //            RestfulServiceFactory rsf = new RestfulServiceFactory(true);
            //            rsf.setUrl(url);
            //            rm = rsf.getService(RegistryManager.class);
            //            this.registryUrl = url;
        } else {
            // local file mode
            rm = new LocalRegistryManager();
            this.parseToLocalRegistry(url);
            this.registryUrl = url;
        }
    }

    public void registry(Provider provider, List<Service> services) {
        rm.registry(provider, services);
        //TODO retry
    }

    public List<Endpoint> listEndpoint(Class<?> api) {
        return rm.listEndpoint(api.getName());
    }

    protected RegistryManager getRegistryManager() {
        return rm;
    }

    public void setRegistryManager(RegistryManager rm) {
        this.rm = rm;
    }

    public String getRegistryUrl() {
        return registryUrl;
    }

    private void parseToLocalRegistry(String path) {
        List<String> lines = StreamReader.readLines(this.getClass().getResourceAsStream(path));
        for (String line : lines) {
            String[] data = line.split("=");
            if (data.length != 2) {
                continue;
            }

            String api = data[0].trim();
            String urls = data[1].trim();
            if (isBlank(api) || isBlank(urls)) {
                continue;
            }

            Service info = new Service();
            info.setId(ObjectId.get().toString());
            info.setServiceMapping(null);
            info.setInterfaceName(api);

            System.out.println("Service -> " + info);

            String[] sps = urls.split("[,; ]");
            for (String txt : sps) {
                if (isBlank(txt)) {
                    continue;
                }
                try {
                    // update service mapping
                    info.setServiceMapping(this.parseServiceUri(txt));

                    Provider sp = this.parseServiceProvider(txt);
                    rm.registry(sp, Collections.singletonList(info));
                } catch (Exception e) {
                    throw new RuntimeException("Provider url format error! [" + txt + "]");
                }
            }
            System.out.println("-----\n");
        }
    }

    private String parseServiceUri(String txt) throws MalformedURLException {
       return new URL(txt).getPath();
    }

    private Provider parseServiceProvider(String txt) throws MalformedURLException {
        URL url = new URL(txt);

        Provider sp = new Provider();
        sp.setId(ObjectId.get().toString());
        sp.setAppId("-");
        sp.setAddress(url.getHost());
        sp.setPort(url.getPort());
        sp.setProtocol(url.getProtocol());
        sp.setEndpoint(url.toString());
        return sp;
    }

    private boolean isBlank(String s) {
        return s == null || s.trim().length() == 0;
    }
}